package com.logic;

import com.logic.common.util.Privileges;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Test {
    static String KEY_STRING = "version,name,type,image,description,status,money,time";
    public static void main(String[] args) throws Exception {
        // generateSql("/Users/vincent/Desktop/landsea/landsea/backend/system-server/src/main/resources/com/logic/system/persistence/read", "/Users/vincent/Desktop/demo.sql");
        generateSql("/Users/vincent/Desktop/landsea/landsea/backend/system-server/src/main/resources/com/logic/landseaserver/persistence/read", "/Users/vincent/Desktop/server.sql");
    }
    /**
     * 生成sql
     * @param dirPath mapper.xml的父级文件夹
     * @param sqlFile 选择你将要生成sql的文件
     * @throws IOException
     */
    private static void generateSql(String dirPath,String sqlFile) throws IOException {
        FileWriter fw = null;
        try {
            File dir = new File(dirPath);
            File sql = new File(sqlFile);
            if (sql.exists()){
                sql.delete();
            }
            sql.createNewFile();
            fw = new FileWriter(sql);

            if (dir.exists() && dir.isDirectory()){
                File[] files = dir.listFiles();
                int count = 0;
                for (File file : files) {
                    count++;
                    if (file.isFile() && file.getName().endsWith(".xml")){
                        System.out.println("正在解析第"+count+"个!");
                        System.out.println(file.getName());
                        if(!file.getName().contains("UserFileReadMapper")){
                            continue;
                        }
//                        if(file.getName().contains("FormReadMapper")
//                            || file.getName().contains("MyProfileReadMapper")
//                            || file.getName().contains("ProcessReadMapper")
//                            || file.getName().contains("RemouldProjectListReadMapper")
//                            || file.getName().contains("WebankReconciliationReadMapper")){
//                            continue;
//                        }
                        fw.append("\r\n");
                        fw.append(getSql(file));
                        fw.flush();
                    }
                }
                System.out.println("共解析了"+count+"个!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if (fw != null)
                fw.close();
        }
    }

    private static String getSql(File xmlfile) throws DocumentException {
        SAXReader saxReader= new SAXReader();
        Document document = saxReader.read(xmlfile);
        org.dom4j.Element root = document.getRootElement();
        Element resultMap = root.element("resultMap");
        Tab tab = new Tab();
        tab.setTableName(getTableName(root));
        tab.setColumns(getColumns(resultMap));
        return tab.toString();
    }
    private static Map<String,String> getColumns(Element resultMap){
        List<Element> elements = resultMap.elements();
        Map<String,String> map = new LinkedHashMap<String, String>();
        for (Element element : elements) {
            if(null == element.attribute("column")){
                continue;
            }
            if(null == element.attribute("jdbcType")){
                continue;
            }
            String column = element.attribute("column").getValue();
            if(KEY_STRING.contains(column.toLowerCase())){
                column = "`"+column+"`";
            }
            map.put(column, element.attribute("jdbcType").getValue());
        }
        return map;
    }
    private static String getTableName(Element root){
        Element selectByPrimaryKey = root.element("select");
        String selectStr = selectByPrimaryKey.getTextTrim();
        System.out.println(selectStr);
        String tableName = "";
        if(selectStr.contains("FROM")){
            tableName = selectStr.split("FROM")[1].trim().split(" ")[0].trim();
        }else{
            tableName = selectStr.split("from")[1].trim().split(" ")[0].trim();
        }
        return tableName;
    }
}

class Tab {

    private String tableName;

    private String idName;

    private String idType;

    private Map<String,String> columns;

    public String getTableName() {
        return tableName;
    }
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
    public String getIdName() {
        return idName;
    }
    public void setIdName(String idName) {
        this.idName = idName;
    }
    public String getIdType() {
        return idType;
    }
    public void setIdType(String idType) {
        this.idType = idType;
    }
    public Map<String, String> getColumns() {
        return columns;
    }
    public void setColumns(Map<String, String> columns) {
        this.columns = columns;
    }
    @Override
    public String toString() {

        StringBuffer sb = new StringBuffer("DROP TABLE  IF EXISTS "+tableName+";");
        sb.append("\r\n");
        sb.append("CREATE TABLE ");
        sb.append(tableName);
        sb.append("(");
        sb.append("\r\n");
        Set<Map.Entry<String,String>> set = columns.entrySet();
        int size = set.size();
        int i = 0;
        for (Map.Entry<String,String> entry : set) {
            i++;
            sb.append("\t"+entry.getKey()+" "+format(entry.getValue()));
            if (size != i){
                sb.append(" ,");
                sb.append("\r\n");
            }

        }
        sb.append("\r\n");
        sb.append(");");
        sb.append("\r\n");
        return sb.toString();

    }
    private String format(String val){
        if (val.equals("VARCHAR")){
            return "VARCHAR(255)";
        }
        if(val.equals("LONGVARCHAR")){
            return "LONGTEXT";
        }
        return val;
    }


}
